<?php
namespace app\admin\controller;

use app\admin\model\Car as CarModel;
use app\admin\model\Account as AccountModel;
use app\admin\model\Device as DeviceModel;
use think\Db;
use think\Request;

class CarManage extends Base
{
    public function index()
    {
        $model = new CarModel;
        $aModel = new AccountModel;
        $dModel = new DeviceModel;

        //渲染页面模板

        $m = $model->field('c.id,c.car_brand,c.car_model,c.plate_number,c.created_at,c.updated_at,d.name as dname,d.imei, u.username')
            ->alias('c')
            ->join('device d','c.device_id = d.id ','left')
            ->join('user u','c.user_id = u.id','left')
            ->order('c.id','desc');
        //->select();
        // ->paginate(5);

        //搜索名称
        $phname = $this->request->param("phname");

        if(!empty($phname)){
            $m =  $m->where('c.plate_number','like', '%'.$phname.'%');
        }
        $result = $m->paginate(10,false,[
            'query'=>['phname'=>$phname]
        ]);

        //渲染用户组
        $account = $aModel->field('id,username')->select();
        //渲染代理商
        $device = $dModel->alias('d')->field('d.id,s.sn')
            ->join('sn s', 's.id=d.sn_id', 'left')->select();

        //计算总共记录条数
        $count = $result->total();
        //分页
        $page = $result->render();

        //接收ajax传递的值
        $request = request();
        $ispost = $request->isPost();
        if($ispost){
            $id = $_POST["viewId"];
            $view = $model->getAll()->where("id",$id)->find();
            return json([
                'code' => 200,
                'view'=>$view,
            ]);
        }


        $this->assign('currentPage',$result->currentPage());
        $this->assign('lastPage',$result->lastPage());
        $this->assign('page',$page);
        $this->assign('account',$account);
        $this->assign('device',$device);
        $this->assign('carmanage',$result);
        $this->assign('count',$count);
        $this->assign('empty',"暂无数据");
        return $this->fetch();
    }

    //新增数据
    public function create(){
        $model = new CarModel;
        //接收ajax传递的值
        $ispost = $this->request->isPost();
        if($ispost){
            $formdata = $this->request->post();

            $result = $model->allowField(true)->save($formdata);

            if($result == 1){
                return json([
                    'code' => 200,
                ]);
            }

        }
    }

    //修改数据处理
    public function edit($id)
    {
        $model = new CarModel;
        //接收ajax传递的值
        $ispost = $this->request->isPost();

        if($ispost){
            $formdata = $this->request->post();

            $result = $model->allowField(true)->save($formdata,['id'=>$id]);

            if($result == 1){
                return json([
                    'code' => 200,
                ]);
            }

        }
    }

    //删除单条记录
    public function delete($id)
    {
        $result = CarModel::update(['deleted_at'=>date('Y-m-d H:i:s')],['id'=>$id]);//软删除

        if($result){
            return json([
                'code' => 200,
            ]);
        }

    }

    //批量删除
    public function deleteArr()
    {
        $ispost = $this->request->isPost();
        if ($ispost) {
            $idArr = $this->request->post();

            $result = CarModel::where('id','exp','in('.implode(',',$idArr['id']).')')->update(['deleted_at'=>date('Y-m-d H:i:s')]);//软删除

            if($result){
                return json([
                    'code' => 200,
                ]);
            }

        }
    }

    // 从mongodb获取最近一次的告警数据
    public function getLastAlarmData() {
        try {
            $deviceId = $this->request->param('device_id');
            $validateResult = $this->validate(['device_id'=>$deviceId],
                ['device_id|设备ID' => ['require', 'regex' => \jm\helper\Check::$regexpArray['id']]],
                ['device_id.regex' => '设备ID无效']
            );
            if (true !== $validateResult) {
                return json(['errcode'=>4001, 'message'=>$validateResult]);
            }

            $imei = \think\Db::name('device')->where('id', $deviceId)->value('imei');
            if (is_null($imei)) {
                return json(['errcode'=>4002, 'message'=>'该设备不存在IMEI，无法获取告警数据']);
            }

            //查找mongo数据库
            $conn = \jm\helper\Db::getMongoIns();
            $filter = [
                'alarm_device_id' => ['$eq' => $imei * 1]
            ];
            $option = [
                // 'projection' => ['alarm_device_id' => 1, 'alarm_address' => 1, 'alarm_latlng' => 1, 'alarm_type' => 1, 'alarm_date' => 1],
                'limit' => 1,
                'sort' => ['alarm_date' => -1]
            ];
            $query = new \MongoDB\Driver\Query($filter, $option);//查询请求
            $rows = $conn->executeQuery('yunjing.alarms', $query); // 执行查询

            $row = [];
            foreach ($rows as $v) {
                $row = $v;
                break;
            }

            return json([
                'errcode' => 200,
                'message' => '查询数据成功',
                'data' => $row
            ]);
        } catch (\Exception $e) {
            return json(['errcode'=>4000, 'message'=>$e->getMessage()]);
        }
    }

    // 实时位置
    public function jmGPS() {
        try {
            // action=one 单个设备的实时位置，此时必须有imei，否则报错；
            // action=all 时获取所有设备的imei，不必传递imei；
            $action = $this->request->param('action', 'one', 'trim,htmlspecialchars');
            $imei = $this->request->param('imei', '', 'trim,htmlspecialchars');

            $validateResult = $this->validate(
                [
                    'action' => $action,
                    'imei' => $imei
                ],
                [
                    'action' => ['require', 'regex' => '/^(one|all)$/']
                ]
            );
            if (true !== $validateResult) {
                return json(['errcode'=>4001, 'message'=>$validateResult]);
            }

            if ($action === 'one' && $imei === '') {
                return json(['errcode'=>4001, 'message'=>'缺少imei']);
            }

            $redis = \jm\helper\Db::getRedisIns();

            $retData = [];
            // 所有设备的最新定位点
            if ($action === 'all') {
                $data = $redis->hGetAll('devices');
                if (!empty($data)) {
                    foreach ($data as $key => $device) {
                        if ($device !== false) {
                            $deviceData = json_decode($device, true);
                            array_push($retData, [
                                'imei' => $deviceData['device_id'],
                                'device_address' => $deviceData['device_address'],
                                'device_latlng' => $deviceData['device_latlng']['coordinates'],
                                'device_loctime' => $deviceData['device_loctime'] * 1000
                            ]);
                        }
                    }
                }
            } else {
                $data = $redis->hget('devices', $imei);
                if ($data !== false) {
                    $deviceData = json_decode($data, true);
                    array_push($retData, [
                        'imei' => $deviceData['device_id'],
                        'device_address' => $deviceData['device_address'],
                        'device_latlng' => $deviceData['device_latlng']['coordinates'],
                        'device_loctime' => $deviceData['device_loctime'] * 1000
                    ]);
                }
            }

            return json(['errcode'=>200, 'message'=>'获取数据成功', 'data'=>$retData]);
        } catch (\Exception $e) {
            return json(['errcode'=>4000, 'message'=>$e->getMessage()]);
        }
    }

    // 单个设备的历史轨迹（可按时间段查询）
    public function orbit()
    {
        try {
            // 时间范围：是按多少天计算呢，还是传递开始时间和结束时间；暂时按开始时间和结束时间；
            $beginTime = $this->request->param('begin_time', '', 'trim,htmlspecialchars');
            $endTime = $this->request->param('end_time', '', 'trim,htmlspecialchars');
            $imei = $this->request->param('imei', '', 'trim,htmlspecialchars');

            $validateResult = $this->validate(
                [
                    'beginTime' => $beginTime,
                    'endTime' => $endTime,
                    'imei' => $imei,
                ],
                [
                    'startTime|开始时间' => 'date',
                    'endTime|结束时间' => 'date',
                    'imei|设备IMEI' => 'require',
                ]
            );
            if (true !== $validateResult) {
                return json(['errcode'=>4001, 'message'=>$validateResult]);
            }

            if ( (empty($beginTime) && !empty($endTime)) || (empty($endTime) && !empty($beginTime)) ) {
                return json(['errcode'=>4002, 'message'=>'必须同时指定开始时间和结束时间']);
            }

            $conn = \jm\helper\Db::getMongoIns();
            $filter = [
                'device_id' => ['$eq' => $imei * 1]
                // 'device_loctime' => ['$gte' => strtotime($data['start_time']), '$lte' => strtotime($data['end_time'])]
            ];
            $option = [
                // 'rejection' => ['_id' => 1, 'device_id' => 1],// 不查询这些字段；
                // 'projection' => ['_id' => 1, 'device_id' => 1],// 只查询这些字段；这两个是php扩展特有的，而不是mongodb有的东西；
                // 'projection' => ['device_id' => 1, 'device_address' => 1, 'device_latlng' => 1, 'device_loctime' => 1],
                'skip' => 0,
                'limit' => 30,
                'sort' => ['device_loctime' => -1]
            ];

            if (!empty($beginTime) && !empty($endTime)) {
                $filter['device_loctime'] = ['$gte' => strtotime($beginTime), '$lte' => strtotime($endTime)];
                unset($option['skip'], $option['limit']);
            }

            $retData = [];
            $query = new \MongoDB\Driver\Query($filter, $option);//查询请求
            $rows = $conn->executeQuery('yunjing.locs', $query); // 执行查询

            foreach ($rows as $v) {
                array_push($retData, [
                    'device_address' => $v->device_address,
                    'device_latlng' => $v->device_latlng->coordinates,
                    'device_loctime' => $v->device_loctime * 1000
                ]);
            }
            return json(['errcode'=>200, 'message'=>'获取行车轨迹数据成功', 'data'=>$retData]);
        } catch (\Exception $e) {
            return json(['errcode'=>4000, 'message'=>$e->getMessage()]);
        }
    }
}